package test.data_structure.array;

public class MyArray<T> {

    private int size;

    private T[] data;

    public MyArray(int capacity) {
        data = (T[])new Object[capacity];
        this.size = 0;
    }

    public MyArray() {
        this(10);
    }

    public int getCapacity() {
        return data.length;
    }

    public int getSize() {
        return this.size;
    }

    public boolean isEmpty() {
        return this.size == 0;
    }

    public void add(int index, T d) {
        if (size == data.length) {
            throw new IllegalArgumentException("Array is full, add failed.");
        }

        if (index < 0 || index > size) {
            throw new IllegalArgumentException("Add failed, index must be in 0~size");
        }

        for (int i = size - 1; i >= index ; i--) {
            data[i + 1] = data[i];
        }
        data[index] = d;
        size++;
    }

    public void addLast(T d) {
        add(size, d);
    }

    public void addFirst(T d) {
        add(0, d);
    }

    public T get(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index is illegal, must be in 0~size-1");
        }
        return data[index];
    }

    public void set(int index, T d) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index is illegal, must be in 0~size-1");
        }
        data[index] = d;
    }

    public int find(T d) {
        for (int i = 0 ; i < size ; i ++) {
            if (d.equals(data[i])) {
                return i;
            }
        }
        return -1;
    }

    public boolean contains(T d) {
        int index = find(d);
        return (index != -1);
    }

    public T remove(int index) {
        if (index < 0 || index >=size) {
            throw new IllegalArgumentException("index is illegal, remove failed.");
        }
        T ret = data[index];
        for (int i = index ; i < size - 1; i ++) {
            data[i] = data[i + 1];
        }
        size --;
        data[size] = null;
        return ret;
    }

    public T removeLast() {
        return remove(size - 1);
    }

    public T removeFirst() {
        return remove(0);
    }

    public void removeElement(T d) {
        int index = find(d);
        if (index != -1) {
            remove(index);
        }
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(String.format("Array size=%d, capacity=%d.", size, data.length));
        stringBuilder.append("[");
        for (int i = 0 ; i < size ; i ++) {
            stringBuilder.append(data[i]);
            if (i != size - 1) {
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

}
